/******************************************************************************/
/* File: dataStore.h                                                          */
/******************************************************************************/

#ifndef DATASTORE_H
#define DATASTORE_H

#include <map>
#include <list>
#include <pthread.h>
#include "thread.h"
#include "socketClass.h"
#include "flowConfig.h"
#include "messageQueue.h"

/******************************************************************************/
/*
 class Arguments
 
 用于参数信息.
 */
/******************************************************************************/
class Arguments {
public:
    Arguments() : sServerIP(NULL), sFileName(NULL), iServerPort(-1),
                  iRole(-1), bUseIPv6(false) {
        
    }
    
    ~Arguments() {
        
    }
    
public:
    int iServerPort;
    char *sServerIP;
    char *sFileName;
    int iRole;
    bool bUseIPv6;
};

/******************************************************************************/
/*
 class CtrlServerSetting
 */
/******************************************************************************/
class GeneralSetting {

public:

    GeneralSetting() : iReportInterval(2000000), 
                       iUpdateInterval(500000),
                       iTCPBufferLength(16 * 1024),
                       iUDPBufferLength(1470),
                       iNumOnce(5) {
                           
    }
    
    ~GeneralSetting() {
        
    }

public:
    unsigned long iReportInterval;  // 报告时间间隔
    unsigned long iUpdateInterval;  // 更新时间间隔
    int iTCPBufferLength;
    int iUDPBufferLength;
    int iNumOnce;
};

/******************************************************************************/
/*
 class CtrlServerSetting
 */
/******************************************************************************/
class CtrlServerSetting {
    
public:
    CtrlServerSetting() : sFileName(NULL), sHostName(NULL),
        iLocalPort(16000), iBackLog(1), bUseIPv6(false) {

    }
    
    ~CtrlServerSetting() {
        if(sFileName) {
            delete sFileName;
            sFileName = NULL;
        }
        
        if(sHostName) {
            delete sHostName;
            sHostName = NULL;
        }
    }
    
public:
    char *sFileName;
    char *sHostName;
    int iLocalPort;
    int iBackLog;
    bool bUseIPv6;
};

/******************************************************************************/
/*
 class TrafficServerSetting
 */
/******************************************************************************/
class TrafficServerSetting {
    
public:
    TrafficServerSetting() : sHostName(NULL),
        iTcpTrafficServerListenPort(16024),
        iUdpTrafficServerListenPort(16016),
        iBackLog(1), bUseIPv6(false) {
        
    }
    
    ~TrafficServerSetting() {
        if(sHostName) {
            delete sHostName;
            sHostName = NULL;
        }
    }
    
public:
    char *sHostName;
    int iUdpTrafficServerListenPort;
    int iTcpTrafficServerListenPort;
    int iBackLog;
    bool bUseIPv6;
};

/******************************************************************************/
/*
 class ConnectionInfo
 
 ConnectionInfo 主要用于保存一条数据流的信息，包括数据流的发送端和接收端地址信息，以及
 使用的协议和本机角色。
 
 ConnectionInfo信息主要保存在每个CtrlClient的数据库中，CtrlClient利用该信息可以查找具
 体每个数据流处理线程的配置信息，从而可以通过该配置信息进行线程行为控制。
 */
/******************************************************************************/
class ConnectionInfo {

public:
    ConnectionInfo() : sSenderIP(NULL), sRecverIP(NULL) {

    } 
    
    ~ConnectionInfo() {
        if(sSenderIP) {
            delete sSenderIP;
            sSenderIP = NULL;
        }
        
        if(sRecverIP) {
            delete sRecverIP;
            sRecverIP = NULL;
        }
    }

public:
    char *sSenderIP;
    int iSenderPort;
    char *sRecverIP;
    int iRecverPort;
    int iProto;
    int iRole;
};

/******************************************************************************/
/*
 class FlowInfo
 
 FlowInfo主要用于保存每条数据流的信息，主要包括流的发送及接收端地址信息，流配置信息。
 
 FlowInfo信息主要存储在CtrlServer的数据库之中，CtrlServer将此数据暴露给用户，用户可以
 直观地看到整个系统中有多少数据流，以及它们的详细信息。
 */
/******************************************************************************/
class FlowInfo {

public:  
    FlowInfo() :sSenderIP(NULL), sRecverIP(NULL), pfc(NULL) {
        
    }
    
    ~FlowInfo() {
        if(sSenderIP) {
            delete sSenderIP;
            sSenderIP = NULL;
        }
    
        if(sRecverIP) {
            delete sRecverIP;
            sRecverIP = NULL;
        }
    
        if(pfc) {
            delete pfc;
            pfc = NULL;
        }
    }
    
public:
    int iFlowID;
    char *sSenderIP;
    int iSenderPort;
    char *sRecverIP;
    int iRecverPort;
    FlowConfig *pfc;
};

/******************************************************************************/
/*
 class CtrlClientInfo
 
 CtrlClientInfo主要用于保存CtrlClient的连接信息。之所以设置该结构体，主要是为了方便CtrlServer
 查找到指定的CtrlClient，然后提取出地址信息，然后发送指令，操作系统
 */
/******************************************************************************/
class CtrlClientInfo {

public:
    CtrlClientInfo() : sCtrlClientIP(NULL), sConnectedIP(NULL) {
    
    }
    
    ~CtrlClientInfo() {
        if(sCtrlClientIP) {
            delete sCtrlClientIP;
            sCtrlClientIP = NULL;
        }
        
        if(sConnectedIP) {
            delete sConnectedIP;
            sConnectedIP = NULL;
        }
    }
    
public:
    char *sCtrlClientIP;
    int iCtrlClientPort;
    char *sConnectedIP;
    int iConnectedPort;
};

/******************************************************************************/
/*
 class ThreadInfo
 */
/******************************************************************************/
class ThreadConf {

public:
    ThreadConf() : iToUpdate(0), iToHalt(0), 
        iStarted(0), iStopped(0),
        pFC(NULL), pMQ(NULL) {

    }
    
    ~ThreadConf() {

    }
    
    /***********************************************/
    // flag为1，则表示需要更新
    void SetUpdateFlag(int flag) {
        try {
            CriticalSection cs(&mMutex);
            iToUpdate = flag;
        } 
        catch (ThreadException te) {
            te.PrintException();
        }
    }
    
    // 获取是否更新的值
    int GetUpdateFlag() {
        try {
            CriticalSection cs(&mMutex);
            return iToUpdate;
        } 
        catch (ThreadException te) {
            te.PrintException();
            return 0;
        }
    }
    
    /***********************************************/
    // flag为1，则表示需要停止线程
    void SetHaltFlag(int flag) {
        try {
            CriticalSection cs(&mMutex);
            iToHalt = flag;
        } 
        catch (ThreadException te) {
            te.PrintException();
        }
    }
    
    // 获取是否需要停止的标志
    int GetHaltFlag() {
        try {
            CriticalSection cs(&mMutex);
            return iToHalt;
        } 
        catch (ThreadException te) {
            te.PrintException();
            return 0;
        }
    }
    
    /***********************************************/
    // flag为1，则表示程序已停止
    void SetStoppedFlag(int flag) {
        try {
            CriticalSection cs(&mMutex);
            iStopped = flag;
        } 
        catch (ThreadException te) {
            te.PrintException();
        }
    }
    
    // 获取程序是否已经停止的标志
    int GetStoppedFlag() {
        try {
            CriticalSection cs(&mMutex);
            return iStopped;
        } 
        catch (ThreadException te) {
            te.PrintException();
            return 0;
        }
    }
    
    /***********************************************/
    // flag为1，则表示程序已启动
    void SetStartedFlag(int flag) {
        try {
            CriticalSection cs(&mMutex);
            iStarted = flag;
        } 
        catch (ThreadException te) {
            te.PrintException();
        }
    }
    
    // 获取程序是否已经启动
    int GetStartedFlag() {
        try {
            CriticalSection cs(&mMutex);
            return iStarted;
        } 
        catch (ThreadException te) {
            te.PrintException();
            return 0;
        }
    }
    
public:
    int iToUpdate;   // 是否需要更新流配置
    int iToHalt;     // 是否需要停止流量线程
    int iStarted;  // 线程是否已启动
    int iStopped;  // 线程是否已停止
    FlowConfig *pFC;
    MessageQueue *pMQ;
    
    // 加锁
    Mutex mMutex;
};

/***********************************************************************/
/*
DataBase类包含了核心数据，主要分为下面几部分内容：
1. 几张表格
2. 几个链表
*/
/***********************************************************************/
class DataStore {

public:
    // 通用设置
    static GeneralSetting generalSetting;

    // 静态成员函数 - 插入，删除，查找存在性，访问map需要加锁 -- CtrlClient信息管理
    static pthread_t FindFlowThread(ConnectionInfo *pci);
    static ThreadConf* FindFlowThreadConf(pthread_t pid);
    static void AddNewFlowThread(Thread *pt, ConnectionInfo *pci, ThreadConf *ptc);
    static void RemoveFlowThread(ConnectionInfo *target);

    // 静态成员函数 -- 插入，删除 -- CtrlServer信息管理
    static TCPSocket * FindCtrlClientSocket(CtrlClientInfo *pcci);
    static TCPSocket * SearchCtrlClientSocket(char *CtrlClientIP);
    static std::list<FlowInfo*> FindCtrlClientFlows(TCPSocket *pts);
    static void AddNewCtrlClient(TCPSocket *pts);
    static void RemoveCtrlClient(TCPSocket *pts);
    
public:
    // 静态成员变量 -- CtrlClient保存
    static Mutex threadIdThreadMapMutex;
    static Mutex connectionThreadIdMutex;
    static Mutex threadIdConfMapMutex;
    static std::map<pthread_t, Thread *> threadIdThreadMap;
    static std::map<ConnectionInfo *, pthread_t> connectionThreadIdMap;
    static std::map<pthread_t, ThreadConf *> threadIdConfMap;
    
    // 静态成员变量 -- CtrlServer保存
    static std::list<TCPSocket *> clientList;
    static std::map<CtrlClientInfo *, TCPSocket *> clientSocketMap;
    static std::map<TCPSocket *, std::list<FlowInfo*> > clientFlowsMap;
};

#endif
/******************************************************************************/
/* End File: dataStore.h                                                      */
/******************************************************************************/